package com.wkbb.sports.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.base.Stopwatch;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.wkbb.common.base.BaseServiceImpl;
import com.wkbb.common.dto.ResultDTO;
import com.wkbb.common.dto.basic.StudentInfoDto;
import com.wkbb.common.dto.basic.UserDto;
import com.wkbb.common.enums.RoleTypeEnum;
import com.wkbb.common.utils.DateUtil;
import com.wkbb.sports.dto.*;
import com.wkbb.sports.enums.SportsHomeContentEnum;
import com.wkbb.sports.enums.SportsModelTypeEnum;
import com.wkbb.sports.enums.SportsProjectTypeEnum;
import com.wkbb.sports.enums.SportsUnitEnum;
import com.wkbb.sports.exception.MyException;
import com.wkbb.sports.exception.ResultEnum;
import com.wkbb.sports.feign.BasicFeignService;
import com.wkbb.sports.mapper.*;
import com.wkbb.sports.model.*;
import com.wkbb.sports.service.RuleService;
import com.wkbb.sports.service.WorkService;
import com.wkbb.sports.utils.DateUtils;
import com.wkbb.sports.utils.MatchRule;
import com.wkbb.sports.utils.RedisOfRank;
import com.wkbb.sports.utils.SportsUtils;
import io.lettuce.core.RedisCommandTimeoutException;
import io.lettuce.core.RedisConnectionException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import redis.clients.jedis.exceptions.JedisDataException;

import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author lbh
 * @date 2021年03月29日 17:58:34
 * @description: 作业实现类
 */
@Slf4j
@Service("workService")
public class WorkServiceImpl extends BaseServiceImpl<HlifeWork> implements WorkService {

    @Autowired
    private HlifeWorkMapper workMapper;

    @Autowired
    private HlifeWorkRuleMapper hlifeWorkRuleMapper;

    @Autowired
    private HlifeWorkStudentMapper hlifeWorkStudentMapper;

    @Autowired
    private HlifeWorkStudentHistoryMapper hlifeWorkStudentHistoryMapper;

    @Autowired
    private HlifePhysicalMapper hlifePhysicalMapper;

    @Autowired
    private HlifeUserMapper hlifeUserMapper;

    @Autowired
    private BasicFeignService basicFeignService;

    @Autowired
    private RuleService ruleService;

    @Autowired
    private RedisOfRank redisOfRank;
    @Autowired
    BasicMapper basicMapper;

    /*#可迁移至nacos进行配置化管理
    #针对某一个作业的提醒次数上限配置，配置成1000次几乎约等于不设置限制，可以自己修改
    count = 1000
    #默认间隔60分钟(即一小时)一次
    interval=60*/

    //针对某一个作业的提醒次数上限配置，配置成1000次几乎约等于不设置限制，可以自己修改
//    @Value("${count}")
    int totalCount=1000;

    //默认间隔60分钟(即一小时)一次
//    @Value("${interval}")
    int interval=60;

    //定义一个计时器
    Stopwatch stopWatch = null;

    SimpleDateFormat sdfAlert = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm");

    SimpleDateFormat format = new SimpleDateFormat("yyyy年M月d日");

    SimpleDateFormat format22 = new SimpleDateFormat("yyyy-MM-dd");

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO insertWork(HifeWorkDto hifeWorkDto,UserDto userDto) {

        ////=====================对作业表各业务字段作合法性要求校验====================【begin】====================================
        if(hifeWorkDto.getProjectId() == null ){
            throw new MyException(ResultEnum.PROJECT_ID_IS_NULL);
        }

        if(StringUtils.isEmpty(hifeWorkDto.getProjectName())){
            throw new MyException(ResultEnum.PROJECT_NAME_IS_NULL);
        }

        if(hifeWorkDto.getOrgId() == null ){
            throw new MyException(ResultEnum.ORG_ID_IS_NULL);
        }

        if(hifeWorkDto.getGradeId() == null ){
            throw new MyException(ResultEnum.GRADE_ID_IS_NULL);
        }

        if(StringUtils.isEmpty(hifeWorkDto.getGradeName())){
            throw new MyException(ResultEnum.GRADE_NAME_IS_NULL);
        }

        if(hifeWorkDto.getClassId() == null ){
            throw new MyException(ResultEnum.CLASS_ID_IS_NULL);
        }

        if(StringUtils.isEmpty(hifeWorkDto.getClassName())){
            throw new MyException(ResultEnum.CLASS_NAME_IS_NULL);
        }

        if(hifeWorkDto.getTeacherId() == null){
            throw new MyException(ResultEnum.TEACHER_ID_IS_NULL);
        }

        if(!verifyDate(hifeWorkDto.getBeginTime())){
            throw new MyException(ResultEnum.DATE_FORMAT_IS_ERROR);
        }
        try {
            hifeWorkDto.setBeginTime(sdf.parse(sdf.format(hifeWorkDto.getBeginTime())));
        }catch (Exception e){
            log.info("====日期解析异常========");
        }

        if(!verifyDate(hifeWorkDto.getEndTime())){
            throw new MyException(ResultEnum.DATE_FORMAT_IS_ERROR);
        }
        try {
            hifeWorkDto.setEndTime(sdf.parse(sdf.format(hifeWorkDto.getEndTime())));
        }catch (Exception e){
            log.info("====日期解析异常========");
        }

        /*if(sdf.format(new Date()).compareTo(sdf.format(hifeWorkDto.getBeginTime()))>0){
            throw new MyException(ResultEnum.BEGIN_DATE_MUST_LAGGER_NOW_DATE);
        }*/

        if(sdf.format(hifeWorkDto.getEndTime()).compareTo(sdf.format(hifeWorkDto.getBeginTime()))<0){
            throw new MyException(ResultEnum.END_DATE_MUST_LAGGER_BEGIN_DATE);
        }

        if(StringUtils.isNotEmpty(hifeWorkDto.getRemark())){
            //if(hifeWorkDto.getRemark().length()>100){  //不区分中英文算字符长度
            //if(countCnAndEnStr(hifeWorkDto.getRemark())>200){  //算字节长度
            if(countCnAndEnStr(hifeWorkDto.getRemark())>100){  //算字符长度
                throw new MyException(ResultEnum.WORK_REMARK_IS_TOO_LONG);
            }
        }
        /*if(hifeWorkDto.getStatus() == null || !(hifeWorkDto.getStatus() ==0  ||hifeWorkDto.getStatus() == 1 ||hifeWorkDto.getStatus() == 2 ||hifeWorkDto.getStatus() == 3)){
            throw new MyException(ResultEnum.STATUS_IS_ILLEGAL);
        }*/

        ////=====================对作业表各业务字段作合法性要求校验====================【end】====================================

        ////=====================对作业要求表各业务字段作合法性要求校验====================【begin】====================================
        HlifeWorkRule hlifeWorkRule=hifeWorkDto.getHlifeWorkRule();
        hlifeWorkRule.setOrgId(hifeWorkDto.getOrgId());

        if(hlifeWorkRule.getProjectType() == null || !(hlifeWorkRule.getProjectType().equals(SportsProjectTypeEnum.EXAMINE.getValue()) || hlifeWorkRule.getProjectType().equals(SportsProjectTypeEnum.PHYSICAL.getValue()))){
            throw new MyException(ResultEnum.PROJECT_TYPE_IS_ILLEGAL);
        }

        if(hlifeWorkRule.getTeacherId() == null ){
            throw new MyException(ResultEnum.TEACHER_ID_IS_NULL);
        }

        if(hlifeWorkRule.getModelType() == null || !(hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.MOCKS.getValue()) || hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.LIMIT.getValue()) || hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.COUNT.getValue()) || hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.TIME.getValue()))){
            throw new MyException(ResultEnum.MODEL_TYPE_IS_ILLEGAL);
        }

        if(hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.MOCKS.getValue())){
            if(hlifeWorkRule.getProjectRuleId() == null ){
                throw new MyException(ResultEnum.PROJECT_RULE_ID_IS_NULL);
            }
        }

        if(hlifeWorkRule.getSex() == null || !(hlifeWorkRule.getSex() == 1 || hlifeWorkRule.getSex() == 2 || hlifeWorkRule.getSex() == 3 || hlifeWorkRule.getSex() == 4)){
            throw new MyException(ResultEnum.SEX_IS_ILLEGAL);
        }

        switch (hlifeWorkRule.getModelType()){
            case 2: //限时限数
                if (hlifeWorkRule.getSex() == 4) { //4区分男女
                    if(hlifeWorkRule.getBoyDuration() == null){
                        throw new MyException(ResultEnum.BOY_DURATION_IS_NULL);
                    }
                    if(hlifeWorkRule.getGirlDuration() == null){
                        throw new MyException(ResultEnum.GIRL_DURATION_IS_NULL);
                    }

                    if(hlifeWorkRule.getBoyNumber() == null){
                        throw new MyException(ResultEnum.BOY_NUMBER_IS_NULL);
                    }
                    if(hlifeWorkRule.getGirlNumber() == null){
                        throw new MyException(ResultEnum.GIRL_NUMBER_IS_NULL);
                    }
                }else{
                    if(hlifeWorkRule.getDuration() == null){
                        throw new MyException(ResultEnum.DURATION_IS_NULL);
                    }
                    if(hlifeWorkRule.getNumber() == null){
                        throw new MyException(ResultEnum.NUMBER_IS_NULL);
                    }
                }
                break;
            case 3: //数量模式
                if (hlifeWorkRule.getSex() == 4) { //4区分男女
                    if(hlifeWorkRule.getBoyNumber() == null){
                        throw new MyException(ResultEnum.BOY_NUMBER_IS_NULL);
                    }
                    if(hlifeWorkRule.getGirlNumber() == null){
                        throw new MyException(ResultEnum.GIRL_NUMBER_IS_NULL);
                    }
                }else{
                    if(hlifeWorkRule.getNumber() == null){
                        throw new MyException(ResultEnum.NUMBER_IS_NULL);
                    }
                }
                break;
            case 4: //时间模式
                if (hlifeWorkRule.getSex() == 4) { //4区分男女
                    if(hlifeWorkRule.getBoyDuration() == null){
                        throw new MyException(ResultEnum.BOY_DURATION_IS_NULL);
                    }
                    if(hlifeWorkRule.getGirlDuration() == null){
                        throw new MyException(ResultEnum.GIRL_DURATION_IS_NULL);
                    }
                }else{
                    if(hlifeWorkRule.getDuration() == null){
                        throw new MyException(ResultEnum.DURATION_IS_NULL);
                    }
                }
                break;
        }
        if(hlifeWorkRule.getUnit() == null || !(hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_MINUTE.getValue()) || hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_SECOND.getValue()))){
            throw new MyException(ResultEnum.UNIT_IS_NULL);
        }

        List<String> studentIdList=hifeWorkDto.getStudentIdList();
        if(CollectionUtils.isEmpty(studentIdList)){
            throw new MyException(ResultEnum.STUDENT_ID_LIST_IS_NULL);
        }

        ////=====================对作业要求表各业务字段作合法性要求校验====================【end】====================================

//        HlifeWork hifeWork=generateHifeWork();
//        System.out.println("=====hifeWork===========:"+JSON.toJSONString(hifeWork));
//        workMapper.insert(hifeWork);

        //hlifeWorkRule.setUnit(3);//默认为分钟3
        hlifeWorkRule.setCreateBy(userDto.getName());
        hlifeWorkRule.setCreateTime(new Date());

//        List<HlifeWorkRule> list1=hlifeWorkRuleMapper.getListByMapParams(new HashedMap());
//        System.out.println("=======list1.size()==========："+list1.size());

        HlifeWork hlifeWork=HlifeWorkRule.generateHifeWork1(hifeWorkDto);
        hlifeWorkRuleMapper.insert(hlifeWorkRule);

//        List<HlifeWorkRule> list2=hlifeWorkRuleMapper.getListByMapParams(new HashedMap());
//        System.out.println("=======list2.size()==========："+list2.size());

        hlifeWork.setRuleId(hlifeWorkRule.getId());
        hlifeWork.setCreateBy(userDto.getName());
        hlifeWork.setTeacherName(userDto.getName());
        hlifeWork.setHeadImgUrl(userDto.getHeadImgUrl());
        hlifeWork.setStatus(0);//默认0未开始
        if(sdf.format(new Date()).compareTo(sdf.format(hifeWorkDto.getBeginTime()))>=0){
            hlifeWork.setStatus(1);//作业开始时间小于等于当前系统时间，则直接设置为进行中 状态(0未开始 1进行中2已结束3已取消)
        }

        List<HlifeWorkStudent> hlifeWorkStudentList= Lists.newArrayList();
        //查询当前作业所选的班级的学生人数
//        ResultDTO<List<StudentInfoDto>>  result = basicFeignService.getStudentInfoListByClassId(Long.valueOf(hifeWorkDto.getOrgId()), Long.valueOf(hifeWorkDto.getClassId()));

        Map<String, Object> hashMap = new HashMap<>();
        hashMap.put("classId",hifeWorkDto.getClassId());
        List<StudentInfoDto> studentInfoDtoList = basicMapper.getStudentInfoList(hashMap);
        if(!studentInfoDtoList.isEmpty()) {
//            List<StudentInfoDto> studentInfoDtoList = result.getData();
            hlifeWork.setTotalCount(studentInfoDtoList.size());
            hlifeWork.setSelectedCount(studentIdList.size());
            workMapper.insert1(hlifeWork);
            studentIdList.forEach(studentUserId-> {
                Optional<StudentInfoDto> optional = studentInfoDtoList.stream().filter(it -> studentUserId.equals(it.getStudentNo())).findFirst();
                if (optional.isPresent()){
                    StudentInfoDto studentInfoDto = optional.get();
                    HlifeWorkStudent hlifeWorkStudent = HlifeWorkRule.generateHifeWorkStudentFromWork(hlifeWork, studentInfoDto, userDto);
                    hlifeWorkStudent.setModelType(hlifeWorkRule.getModelType());
                    hlifeWorkStudentList.add(hlifeWorkStudent);
                }else{
                    log.info("===========studentUserId为：==="+studentUserId+"==的学生查无此人，无法给他绑定当前布置的作业===workid："+hifeWorkDto.getId()+"=========");
                }
            });
            if(!hlifeWorkStudentList.isEmpty()) {
                log.info("===========当前布置的作业===workid"+hifeWorkDto.getId()+"====将绑定到"+hlifeWorkStudentList.size()+"个学生");
                hlifeWorkStudentMapper.insertBatch1(hlifeWorkStudentList);
            }else{
                log.info("===========当前布置的作业===workid"+hifeWorkDto.getId()+"===没有学生可以绑定==========");
            }
        }else {
            return ResultDTO.errorResult("===========当前布置的作业===workid"+hifeWorkDto.getId()+"===没有学生可以绑定==========");
        }
        //故意制造失败测试全局事务是否正常生效，测试成功！
//        workMapper.test();

//        HlifeWorkRule hlifeWorkRule=generateHifeWorkRule();
//        System.out.println("=====hlifeWorkRule===========:"+JSON.toJSONString(hlifeWorkRule));

//        HlifeWorkStudentHistory hlifeWorkStudentHistory=generateHlifeWorkStudentHistory();
//        System.out.println("=====hlifeWorkStudentHistory===========:"+JSON.toJSONString(hlifeWorkStudentHistory));
//        hlifeWorkStudentHistoryMapper.insert(hlifeWorkStudentHistory);

        return new ResultDTO<>("===========当前布置的作业===workid："+hlifeWork.getId()+"====已经成功绑定到"+hlifeWorkStudentList.size()+"个学生");
    }

    public boolean verifyDate(Date date){
        try {
            sdf.format(date);
//            System.out.println("=========日期解析成功==============");
            return true;
        }catch (Exception e){
//            System.out.println("=========日期解析失败=============");
        }
        return false;
    }

    /**
     * 查询学生
     * */
    private HlifeUser getStudentInfo(long orgId, String studentNo) {
        Map<String, Object> params = new HashMap<>();
        params.put("orgId", orgId);
        params.put("userType", (byte) RoleTypeEnum.STUDENT.getValue());
        params.put("userNo", studentNo);
        HlifeUser user = hlifeUserMapper.getByMapParams(params);
        if(user != null) {
            return user;
        }
        ResultDTO<StudentInfoDto> res = basicFeignService.getStudentByStudentNo(orgId, null,null,studentNo);
        if(res.isSuccess()) {
            StudentInfoDto dto = res.getData();
            if(dto != null) {
                HlifeUser hlifeUser = new HlifeUser();
                hlifeUser.setUserType((byte) RoleTypeEnum.STUDENT.getValue());
                hlifeUser.setOrgId(orgId);
                hlifeUser.setOrgName(dto.getOrgName());
                hlifeUser.setGradeId(dto.getGradeId());
                hlifeUser.setGradeName(dto.getGradeName());
                hlifeUser.setClassId(dto.getClassId());
                hlifeUser.setClassName(dto.getClassName());
                hlifeUser.setUserId(dto.getUserId());
                hlifeUser.setUserName(dto.getName());
                hlifeUser.setMobile(dto.getMobile());
                hlifeUser.setSex(SportsUtils.getSexValue(dto.getSex()).byteValue());
                hlifeUser.setHeadImg(dto.getHeadImgUrl());
                hlifeUser.setUserNo(studentNo);
                hlifeUserMapper.insert(hlifeUser);
                return hlifeUser;
            }
        }
        log.warn("can not find student info by studentNo -> " + orgId + ", " + studentNo);
        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO insertWorkStudentHistory(HlifeWorkStudentHistory hlifeWorkStudentHistory, UserDto userDto) {
        hlifeWorkStudentHistory.setCreateBy(userDto.getName());
        //hlifeWorkStudentHistory.setWorkStudentId(hlifeWorkStudentHistory.getId());
        hlifeWorkStudentHistory.setId(null);
        //================计算该学生针对本次作业提交是否达标========begin============
        Map<String, Object> workDetailMap = workMapper.getWorkDetail(hlifeWorkStudentHistory.getWorkId());
        String ruleId = String.valueOf(workDetailMap.get("ruleId"));
        HlifeWorkRule hlifeWorkRule = hlifeWorkRuleMapper.getByPrimaryKey(Long.valueOf(ruleId));
        Integer duration = 0;
        Integer boyDuration = 0;
        Integer girlDuration = 0;

        if (hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.TIME.getValue())) {   //4时间模式，目前只考虑这个模式
            if (hlifeWorkRule.getSex() == 4) { //4区分男女
                if (hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_MINUTE.getValue())) { //3分/4秒
                    boyDuration = hlifeWorkRule.getBoyDuration() * 60;
                    girlDuration = hlifeWorkRule.getGirlDuration() * 60;
                } else { //3分/4秒
                    boyDuration = hlifeWorkRule.getBoyDuration();
                    girlDuration = hlifeWorkRule.getGirlDuration();
                }
            } else {
                if (hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_MINUTE.getValue())) { //3分/4秒
                    duration = hlifeWorkRule.getDuration() * 60;
                } else { //3分/4秒
                    duration = hlifeWorkRule.getDuration();
                }
            }
        }

        boolean reached = false;
        if (hlifeWorkRule.getSex() == 4) {
            Integer actualTime = hlifeWorkStudentHistory.getActualTime();
            if (hlifeWorkStudentHistory.getSex() == 1) {
                reached = boyDuration <= actualTime;
            } else {
                reached = girlDuration <= actualTime;
            }
        } else {
            Integer actualTime = hlifeWorkStudentHistory.getActualTime();
            reached = duration <= actualTime;
        }
        hlifeWorkStudentHistory.setReached(reached?1:0);

        //================计算该学生针对本次作业提交是否达标========end============
        double score = 0.0;
        double plusScore = 0.0;
        /////===================通过成绩achivement计算分数score和加分项得分pluses_score==【begin】================================
        if(hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.MOCKS.getValue())){ //只有模拟考试模式才需要计算分数
                 //根据评分标准ID查询评分标准类型
                String result=workMapper.getMarkTypeByProjectRuleId(hlifeWorkRule.getProjectRuleId());
                Byte markType=Byte.valueOf(result);//评分标准类型(1-国家标准,2-地方标准,3-自定义标准)

                Long orgId=hlifeWorkStudentHistory.getOrgId();
                Byte projectId=hlifeWorkStudentHistory.getProjectId();
                Long gradeId=hlifeWorkStudentHistory.getGradeId();
                Byte sex=hlifeWorkStudentHistory.getSex();
                String achivement=String.valueOf(hlifeWorkStudentHistory.getAchivement());
                List<ScoreRuleDto> rules =Lists.newArrayList();
                try {
                    //此处一旦报异常：UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only
                    //会导致该接口一直报错，影响事务回滚
                    rules = ruleService.queryScoreRuleList(orgId);
                }catch (Exception e){
                    log.info("=======queryScoreRuleList===查询规则出现异常！！===========异常信息为==："+e.getMessage());
                    //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚异常
                }
                List<HlifeOrgGrade> orgGrades = null;
                try {
                	orgGrades = ruleService.queryOrgGradeList(orgId);
                }catch (Exception e){
                    log.info("=======queryOrgGradeList===查询规则出现异常！！===========异常信息为==："+e.getMessage());
                    //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚异常
                }

                if(!(CollectionUtils.isEmpty(rules)) && markType!=null && projectId!=null && gradeId!=null && sex!=null && StringUtils.isNotEmpty(achivement)) {
                    try {
                        MatchRule matchRule = new MatchRule(rules, orgGrades);
                        MatchRule.Entity plusAndScore = matchRule.calculatePhysicalScore(gradeId.longValue(), sex.byteValue(), Double.valueOf(achivement));
                        score = plusAndScore.getScore();
                        plusScore = plusAndScore.getPlusScore();
                    } catch (Exception e) {
                        log.info("=======通过成绩achivement计算分数score和加分项得分pluses_score===出现异常！！==========异常信息为==：" + e.getMessage());
                        //TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚异常
                    }
                }
            }
        /////===================通过成绩achivement计算分数score和加分项得分pluses_score==【end】================================
        hlifeWorkStudentHistory.setHeadImgUrl(userDto.getHeadImgUrl());
        hlifeWorkStudentHistory.setScore(score);
        hlifeWorkStudentHistory.setPlusesScore(plusScore);
        hlifeWorkStudentHistory.setStatus(1);
        if(hlifeWorkStudentHistory.getModelType() == null){
            hlifeWorkStudentHistory.setModelType(4);//给默认值:4时间模式
        }
        hlifeWorkStudentHistoryMapper.insert(hlifeWorkStudentHistory);

        //查询学生本次作业提交历史中的最优成绩//只算已达标的
        HlifeWorkStudentHistory hlifeWorkStudentHistoryOptimal=hlifeWorkStudentHistoryMapper.getHlifeWorkStudentHistoryOptimal(hlifeWorkStudentHistory.getWorkStudentId());
        if(hlifeWorkStudentHistoryOptimal == null){
            //最好的成绩都未达标
            hlifeWorkStudentHistoryOptimal=hlifeWorkStudentHistoryMapper.getHlifeWorkStudentHistoryOptimal1(hlifeWorkStudentHistory.getWorkStudentId());
        }
        /*HlifeWorkStudent hlifeWorkStudent=new HlifeWorkStudent();
        try {
            BeanUtils.copyProperties(hlifeWorkStudent, hlifeWorkStudentHistoryOptimal);
        }catch (Exception e){
            log.info("========e.getMessage()=========:"+e.getMessage());
        }
        if(hlifeWorkStudent.getModelType() == null){
            hlifeWorkStudent.setModelType(4);//给默认值:4时间模式
        }
        hlifeWorkStudent.setId(hlifeWorkStudentHistory.getWorkStudentId());
        hlifeWorkStudent.setWorkId(hlifeWorkStudentHistory.getWorkId());
        hlifeWorkStudent.setStatus(1);
        hlifeWorkStudent.setUpdateBy(userDto.getName());
        hlifeWorkStudent.setUpdateTime(new Date());
        hlifeWorkStudent.setHeadImgUrl(userDto.getHeadImgUrl());*/

        HlifeWorkStudent hlifeWorkStudent=HlifeWorkStudent.generateHlifeWorkStudentFromHistoryDto(hlifeWorkStudentHistory,hlifeWorkStudentHistoryOptimal,userDto);
        hlifeWorkStudentMapper.update(hlifeWorkStudent);
        Long position=0L;
//        方法一：当前提交作业的学生的即时排名【mysql】
//        position=hlifeWorkStudentMapper.getStudentPosition(hlifeWorkStudent.getWorkId().toString(),hlifeWorkStudent.getStudentId().toString());

//        方法二：Redis实现排行榜功能 优化mysql查询的方式，既能够去重又能够保持有序
        try {
            //Long position=redisOfRank.add(hlifeWorkStudent.getWorkId(),hlifeWorkStudent.getStudentId(),hlifeWorkStudent.getScore());
            //position=redisOfRank.add(hlifeWorkStudent);
        }catch (JedisDataException e){
            log.info("=====insertWorkStudentHistory======JedisDataException=============:"+e.getMessage());
        }catch (RedisCommandTimeoutException e){
            log.info("=====insertWorkStudentHistory======RedisCommandTimeoutException=============:"+e.getMessage());
        }catch (RedisConnectionException e){
            log.info("=====insertWorkStudentHistory======RedisConnectionException=============:"+e.getMessage());
        }catch (Exception e){
            log.info("=====insertWorkStudentHistory======Exception=============:"+e.getMessage());
        }
        if(position.equals(0L)){
            String workId1=hlifeWorkStudent.getWorkId().toString();
            log.info("============hlifeWorkStudentHistory.getStudentId()==================:"+hlifeWorkStudentHistory.getStudentId());
            String studentId1=hlifeWorkStudentHistory.getStudentId().toString();
            position=hlifeWorkStudentMapper.getStudentPosition(workId1,studentId1);
        }
        Map<String,Object> resultMap=Maps.newHashMap();
        resultMap.put("position",position);
        resultMap.put("reached",hlifeWorkStudentHistory.getReached());
        resultMap.put("actualTime",hlifeWorkStudentHistory.getActualTime());
        if(hlifeWorkRule.getSex() == 4 && hlifeWorkStudentHistory.getSex() == 1) {
            resultMap.put("duration", ((boyDuration/60)+"分钟"));
        }else if(hlifeWorkRule.getSex() == 4 && hlifeWorkStudentHistory.getSex() == 2) {
            resultMap.put("duration", ((girlDuration/60)+"分钟"));
        }else{
            resultMap.put("duration", ((duration/60)+"分钟"));
        }
        return new ResultDTO<>(resultMap);
        //return new ResultDTO<>();
    }

    /**
     * 当前作业的学生的排名
     * @param workId
     * @return
     */
    @Override
    public ResultDTO getStudentPositionOfWork(String workId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
//        方法一：当前作业的学生的排名【mysql】
//        List<Map<String,Object>>  list=hlifeWorkStudentMapper.getStudentPositionOfWork(workId);

//        方法二：Redis实现排行榜功能 优化mysql查询的方式，既能够去重又能够保持有序
            Set<ZSetOperations.TypedTuple<Map<String,Object>>> rangeWithScores=null;
            Set<String> scores=null;
            try {
                //rangeWithScores = redisOfRank.list(Integer.parseInt(workId));
                //scores = redisOfRank.listScore(Integer.parseInt(workId));
            }catch (JedisDataException e){
                log.info("=====getStudentPositionOfWork======JedisDataException=============:"+e.getMessage());
            }catch (RedisCommandTimeoutException e){
                log.info("=====getStudentPositionOfWork======RedisCommandTimeoutException=============:"+e.getMessage());
            }catch (RedisConnectionException e){
                log.info("=====getStudentPositionOfWork======RedisConnectionException=============:"+e.getMessage());
            }catch (Exception e){
                log.info("=====getStudentPositionOfWork======Exception=============:"+e.getMessage());
            }
            //if(!CollectionUtils.isEmpty(rangeWithScores) && !CollectionUtils.isEmpty(scores) && rangeWithScores.size()==scores.size()) {  //优先取redis
            if(1==2) {  //优先取redis
                //组装数据
                List<Map<String, Object>> resultList = Lists.newArrayList();

                return new ResultDTO<>(resultList);
            } else{  //redis里没有数据再查询数据库并填充redis
    //        当前作业的学生的排名【mysql】
            List<Map<String, Object>> list = hlifeWorkStudentMapper.getStudentPositionOfWork(workId,null); //redis里没有数据再查询数据库
            /*List<Map<String, Object>> listNew = Lists.newArrayList();
            list.forEach(maps -> {
                Map<String, Object> map = Maps.newHashMap();
                Map<String, Object> mapNew = Maps.newHashMap();
                map.put("id", Integer.parseInt(String.valueOf(maps.get("id"))));
                map.put("studentId", Integer.parseInt(String.valueOf(maps.get("studentId"))));
                map.put("studentName", String.valueOf(maps.get("studentId")));
                map.put("headImgUrl", String.valueOf(maps.get("headImgUrl")));
                map.put("workId", String.valueOf(maps.get("workId")));
                mapNew.put("perInfo", map);
                mapNew.put("score", Double.valueOf(String.valueOf(maps.get("score"))));
                listNew.add(mapNew);
            });*/

                try {
                    //redisOfRank.removeAllByWorkId(Integer.parseInt(workId)); //填充redis之前先清空某一个作业的排行榜记录
                    //redisOfRank.batchAdd(Integer.parseInt(workId), listNew); //填充redis
                }catch (JedisDataException e){
                    log.info("=====getStudentPositionOfWork==batchAdd====JedisDataException=============:"+e.getMessage());
                }catch (RedisCommandTimeoutException e){
                    log.info("=====getStudentPositionOfWork==batchAdd====RedisCommandTimeoutException=============:"+e.getMessage());
                }catch (RedisConnectionException e){
                    log.info("=====getStudentPositionOfWork==batchAdd====RedisConnectionException=============:"+e.getMessage());
                }catch (Exception e){
                    log.info("=====getStudentPositionOfWork==batchAdd====Exception=============:"+e.getMessage());
                }

            return new ResultDTO<>(list);
        }
    }

    /**
     * 当前作业的学生的排名【前三名或者含自己的四名】
     * @param workId
     * @param studentId
     * @return
     */
    @Override
    public ResultDTO getStudentPositionOfWorkThird(String workId,String studentId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        if(StringUtils.isEmpty(studentId)){
            throw new MyException(ResultEnum.STUDENT_ID_IS_NULL);
        }
        List<Map<String, Object>> list =Lists.newArrayList();
        Long position=hlifeWorkStudentMapper.getStudentPosition(workId,studentId);//先查一下自己的排名
        if(position>3){ //自己的排名不在前三名
            list = hlifeWorkStudentMapper.getStudentPositionOfWorkThird(workId,studentId); //先从数据库里查询出三条
            List<Map<String, Object>> list1 = hlifeWorkStudentMapper.getStudentPositionOfWork(workId,studentId); //再从数据库里查询出自己的
            list.addAll(list1);
        }else{ //自己的排名在前三名
            list = hlifeWorkStudentMapper.getStudentPositionOfWorkThird(workId,studentId); //直接从数据库里查询出三条
        }
        return new ResultDTO<>(list);
    }

    /**
     * 查询前三名或者含自己的前面的两名
     * @param workId
     * @param studentId
     * @return
     */
    @Override
    public ResultDTO getStudentByPosition(String workId,String studentId,String mark){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        if(StringUtils.isEmpty(studentId)){
            throw new MyException(ResultEnum.STUDENT_ID_IS_NULL);
        }

        List<Map<String, Object>> list =Lists.newArrayList();
        //存在一个问题，某个作业一个学生都没有做，所有的学生的achivement都是0，单独去查询某个学生的排名永远是1，进入else分支，但是查询出来的三条数据又不包括自己
        Long position=hlifeWorkStudentMapper.getStudentPosition(workId,studentId);//先查一下自己的排名(假设是8)
        //查询当前同一个排名的学生人数【并列排名】
        Long number=hlifeWorkStudentMapper.getStudentSamePositionCount(workId,position.toString());

        log.info("===作业id为====："+workId+"===学生id为====："+studentId+"===该学生排名为====："+position+"===【并列排名】的人数为====："+number);
        if(StringUtils.isEmpty(mark)){
            mark="1";
        }

        if(position>3){ //自己的排名不在前三名
            //String positions=String.valueOf((position-2)).concat(",").concat(String.valueOf((position-1))).concat(",").concat(String.valueOf(position));//6,7,8
           /* String positions=getPositionStr(position,mark);
            //查询某个指定作业的指定位置排名的学生们信息(我和最近排在我前面的2名:position-2和position-1是我当前排名的前两名)(in实现)
            list=hlifeWorkStudentMapper.getStudentByPosition(workId, positions.replace(",","','"));*/

            String positionss="";
            if(StringUtils.equals(mark,"0")){  //查询前三名或者含自己的前面的两名
                positionss=String.valueOf((position-2));
            }else{  //查询自己排名前的所有
                positionss="1";
            }
            //查询某个指定作业的指定位置排名的学生们信息(我和最近排在我前面的2名:position-2和position-1是我当前排名的前两名)(between and 实现【效率更高】)
            list=hlifeWorkStudentMapper.getStudentByPosition2(workId, positionss,position.toString(),studentId);

            //if(number>1) {
            //    list.set(list.size()-1, getHlifeWorkStudentById(workId, studentId,list.size()));
                list.add(list.size()-1, getHlifeWorkStudentById(workId, studentId,list.size()));
            //}
        }else{   //自己的排名在前三名

            String total = hlifeWorkStudentMapper.gethWorkStudentCount(workId);//已经做了该作业的学生人数
            if ("0".equals(total)) {  //某个作业一个学生都没有做
                list = hlifeWorkStudentMapper.getStudentPositionOfWorkSecond(workId,studentId); //直接从数据库里查询出前两名
                //所有的学生的achivement都是0，单独去查询某个学生的排名永远是1，进入else分支，但是查询出来的三条数据又不包括自己，所以需要单独查出自己进行数据补偿一下
                list.add(0,getHlifeWorkStudentById(workId,studentId,1));
            }else{
                //但排名有可能并列
                list = hlifeWorkStudentMapper.getStudentPositionOfWorkThird(workId,studentId); //直接从数据库里查询出三条并返回(因为并列，可能还是不包括自己)
                //if(number>1) {
                //    list.set(position.intValue()-1, getHlifeWorkStudentById(workId, studentId));
                    list.add(position.intValue()-1, getHlifeWorkStudentById(workId, studentId,position.intValue()));
                //}
            }
        }
        return new ResultDTO<>(list);
    }

    public static String getPositionStr(Long position,String mark){
        String positions="";
        StringBuffer sb=new StringBuffer();
        if(StringUtils.equals(mark,"0")){  //查询前三名或者含自己的前面的两名
            positions=String.valueOf((position-2)).concat(",").concat(String.valueOf((position-1))).concat(",").concat(String.valueOf(position));//6,7,8
        }else{ //查询自己排名前的所有
            for (int i=1;i<=position;i++){
                sb.append(String.valueOf((i))).append(",");
            }
            positions=sb.deleteCharAt(sb.length()-1).toString();
        }
        return positions;
    }

    //②UTF-8编码中，一个英文字符等于一个字节，一个中文（含繁体）等于三个字节。
    //③Unicode编码中，一个英文等于两个字节，一个中文（含繁体）等于两个字节。
    public static int countCnAndEnStr(String text) {
        try {
            text=text.trim();
            // 要统计的字符串
            // 字符串的字符数量
            int totalLength = text.length();
            // 字符串getBytes后的字符数量
            //int totalBytesLength = text.getBytes().length;//【默认UTF-8编码】，一个英文字符等于一个字节，一个中文（含繁体）等于三个字节。
            //int totalBytesLength = text.getBytes("UTF-8").length;//UTF-8编码中，一个英文字符等于一个字节，一个中文（含繁体）等于三个字节。
            //int totalBytesLength = text.getBytes("ASCII").length;//ASCII编码中，一个英文字符等于一个字节，一个中文（含繁体）等于一个字节。
            //int totalBytesLength = text.getBytes("Unicode").length;//Unicode编码中，一个中文（含繁体）等于四个字节。
            //int totalBytesLength = text.getBytes("GBK").length;//GBK编码中，一个中文（含繁体）等于两个字节。
            int totalBytesLength = text.getBytes("GB2312").length;//GB2312编码中，一个中文（含繁体）等于两个字节。

            // 字符串中中文（含中文符合）字符数量
            int chCharsLength = (text.getBytes().length - totalLength) / 2;//【默认UTF-8编码】，一个中文（含繁体）等于三个字节。
            //totalBytesLength=totalBytesLength-chCharsLength;//变相转换为2个字节的【非GBK/GB2312】

            // 字符串中英文（含符号）、数字字符数量
            int enCharsLength = totalLength - chCharsLength;
            //System.out.println("要统计的字符串是："+text+"=====\n总字符数：" + totalLength + "\n中文字符数："+ chCharsLength + "\n英文字符数" + enCharsLength);

            //把英文字符串折算成中文的个数(两个英文字符算一个中文字符)
            int enCharsToCnLength = enCharsLength % 2 == 0 ? enCharsLength / 2 : enCharsLength / 2 + 1;
            int total = chCharsLength + enCharsToCnLength;
            //System.out.println("要统计的字符串是："+text+"=====总字符数：" + total);
            System.out.println("要统计的字符串是：" + text + "=====字符串getBytes后的字符数量：" + totalBytesLength);
            //System.out.println("========================================");
            //return totalBytesLength;
            return total;
        }catch (UnsupportedEncodingException e){
            e.printStackTrace();
            return 0;
        }
    }

    public Map getHlifeWorkStudentById(String workId,String studentId,int position){
        Map map=Maps.newHashMap();
        Map map1=Maps.newHashMap();
        map.put("studentId",studentId);
        map.put("workId",workId);
        HlifeWorkStudent hlifeWorkStudent=hlifeWorkStudentMapper.getByMapParams(map);
        map1.put("id",hlifeWorkStudent.getId());
        map1.put("studentName",hlifeWorkStudent.getStudentName());
        map1.put("studentId",hlifeWorkStudent.getStudentId());
        map1.put("headImgUrl",hlifeWorkStudent.getHeadImgUrl());
        map1.put("position",position);
        map1.put("score",hlifeWorkStudent.getAchivement());
        map1.put("workId",hlifeWorkStudent.getWorkId());
        map1.put("number",hlifeWorkStudent.getAchivement());
        map1.put("duration",hlifeWorkStudent.getActualTime());
        return map1;
    }
    /**
     * 查询出当前作业已经做的学生的成绩
     * @param workId
     * @return
     */
    @Override
    public List<WebSocketInfoDto> getStudentScoreOfWork(String workId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        return hlifeWorkStudentMapper.getStudentScoreOfWork(workId);
    }

    //    查询项目下拉列表的值
    @Override
    public ResultDTO<List<HlifePhysical>> getItemValue(Long orgId, Long projectType){
        Map map= Maps.newHashMap();
        map.put("orgId",orgId);
        map.put("projectType",projectType);
        List<HlifePhysical> list= hlifePhysicalMapper.getListByMapParams(map);
        return new ResultDTO<>(list);
    }

/*
    //    查询评分标准下拉列表的值
    @Override
    public ResultDTO<List<HlifePhysicalRule>> getValueStandardOfEvaluation(Long physicalId,Long orgId ,Long gradeId){
        Map map= Maps.newHashMap();
        map.put("physicalId",physicalId);
        map.put("orgId",orgId);
        map.put("gradeId",gradeId);
        List<HlifePhysicalRule> list= hlifePhysicalRuleMapper.getListByMapParams(map);
        return new ResultDTO<>(list);
    }
*/

    /**
     *  最近作业列表
     * @param teacherId
     * @param projectId
     * @param classId
     * @param time
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public ResultDTO<PageInfo<WorkDto>> getWorkListByTeacherId(Integer teacherId,Integer projectId,Integer classId,String time,Integer orgId,int pageNo,int pageSize){
        if(teacherId == null){
            throw new MyException(ResultEnum.TEACHER_ID_IS_NULL);
        }
        Map params=Maps.newHashMap();
        params.put("teacherId",teacherId);
        params.put("projectId",projectId);
        params.put("classId",classId);
        params.put("orgId",orgId);
        if(StringUtils.isNotEmpty(time)){
            if(time.indexOf("-")>0){
                params.put("beginTime",verifyDate1(time.split("-")[0]));
                params.put("endTime",verifyDate1(time.split("-")[1]));
            }else{
                params.put("time",verifyDate1(time));
            }
        }
        Page<Map<String,Object>> page = PageHelper.startPage(pageNo, pageSize);
        List<WorkDto> hifeWorkDtoList=workMapper.getWorkListByTeacherId(params);
        if(!CollectionUtils.isEmpty(hifeWorkDtoList)){
            for (int j = 0; j < hifeWorkDtoList.size(); j++) {
                WorkDto workDateDto=hifeWorkDtoList.get(j);
//                log.info("===========workDateDto================："+ JSON.toJSONString(workDateDto));
                String sortTime=workDateDto.getSortTime();//星期，如：星期1
//                double diff=getDoubleMarginZheng(sdf1.format(new Date()),createTime.replace("年","-").replace("月","-").replace("日","-"));
                double diff= workDateDto.getDiff();
                sortTime=getWeekDay(Integer.valueOf(sortTime.replace("星期","")));
                //最近几天就不显示年月日了
                if(diff==0){
                    workDateDto.setFinalTime("今天   "+sortTime);
                }else if(diff==1){
                    workDateDto.setFinalTime("昨天   "+sortTime);
                }else if(diff==2){
                    workDateDto.setFinalTime("前天   "+sortTime);
                }else{
//                    workDateDto.setFinalTime(createTime+" "+sortTime);
                    workDateDto.setFinalTime(DateUtil.toChYmdString(workDateDto.getCreateTime()) + " " + sortTime);
                }
                workDateDto.setCreateTime(null);
                workDateDto.setSortTime(null);
            }
        }
        PageInfo<WorkDto> pageInfo = new PageInfo<>(hifeWorkDtoList);
        pageInfo.setTotal(page.getTotal());
//        return pageInfo;
        return new ResultDTO<>(pageInfo);
//        return new ResultDTO<>(hifeWorkDtoList);
    }

    public String verifyDate1(String time){
        String result="";
        try {
            result=format22.format(format22.parse(time));
            log.info("=====verifyDate1====日期解析成功============result==："+result);
            return result;
        }catch (Exception e){
            log.info("===verifyDate1======日期解析失败=============");
        }
        return result;
    }

    /**
     * 作业详情及统计
     * @param workId
     * @return
     */
    @Override
    @Transactional(readOnly = true)
    public ResultDTO<Map<String,Object>> getWorkDetail(String workId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        Map<String,Object> finalMap=Maps.newHashMap();

        //1、作业信息详情
        Map<String,Object>  workDetailMap=workMapper.getWorkDetail(Long.parseLong(workId));
        String ruleId=String.valueOf(workDetailMap.get("ruleId"));
        workDetailMap.remove("ruleId");
        workDetailMap.put("workId",workId);
        finalMap.put("workDetailMap",workDetailMap);

        //2、作业要求
        Map<String,Object> workRuleMap=Maps.newHashMap();
        HlifeWorkRule hlifeWorkRule=hlifeWorkRuleMapper.getByPrimaryKey(Long.valueOf(ruleId));
        workRuleMap.put("modelType",hlifeWorkRule.getModelType());//模式(1模拟考试 2限时限数 3数量模式 4时间模式)
        workRuleMap.put("sex",hlifeWorkRule.getSex());//性别(1男 2女3不限4区分男女)
        workRuleMap.put("intro",hlifeWorkRule.getIntro());//性别(1男 2女3不限4区分男女)

//        Integer duration=0;
//        Integer boyDuration=0;
//        Integer girlDuration=0;
//        if(hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.TIME.getValue())) {   //4时间模式，目前只考虑这个模式
//            if (hlifeWorkRule.getSex() == 4) { //4区分男女
//                if (hlifeWorkRule.getUnit() == 3) { //3分/4秒
//                    workRuleMap.put("boyDuration", hlifeWorkRule.getBoyDuration().toString().concat("分钟"));
//                    workRuleMap.put("girlDuration", hlifeWorkRule.getGirlDuration().toString().concat("分钟"));
////                    boyDuration = hlifeWorkRule.getBoyDuration() * 60;
////                    girlDuration = hlifeWorkRule.getGirlDuration() * 60;
//                } else { //3分/4秒
//                    workRuleMap.put("boyDuration", hlifeWorkRule.getBoyDuration().toString().concat("秒"));
//                    workRuleMap.put("girlDuration", hlifeWorkRule.getGirlDuration().toString().concat("秒"));
////                    boyDuration = hlifeWorkRule.getBoyDuration();
////                    girlDuration = hlifeWorkRule.getGirlDuration();
//                }
//            }else{
//                if(hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_MINUTE.getValue())){ //3分/4秒
//                    workRuleMap.put("duration",hlifeWorkRule.getDuration().toString().concat("分钟"));
////                    duration=hlifeWorkRule.getDuration()*60;
//                }else{ //3分/4秒
//                    workRuleMap.put("duration",hlifeWorkRule.getDuration().toString().concat("秒"));
////                    duration=hlifeWorkRule.getDuration();
//                }
//            }
//        }
        finalMap.put("workRuleMap",workRuleMap);

        //3、作业完成情况
//        Map<String,Object> workStudentMap=Maps.newHashMap();
//        List<HlifeWorkStudent> unReachedList=hlifeWorkStudentMapper.gethWorkStudentDetail(workId,"0");//未达标
//        List<HlifeWorkStudent> reachedList=hlifeWorkStudentMapper.gethWorkStudentDetail(workId,"1");//已达标
//        workStudentMap.put("reachedList",reachedList);
//        workStudentMap.put("unReachedList",unReachedList);
//        finalMap.put("workStudentMap",workStudentMap);
        return new ResultDTO<>(finalMap);
    }

    @Override
    @Transactional(readOnly = true)
    public ResultDTO<Map<String,Object>> getWorkStudentByDate(String workId,String date){
        Map<String,Object> finalMap=Maps.newHashMap();
        List<WorkStuDto> studentList = hlifeWorkStudentMapper.getWorkStuList(workId);
        //重新date统计数据
        List<WorkStuDto> list = hlifeWorkStudentHistoryMapper.getWorkStudentByDate(workId,date);

        List<WorkStuDto> reachedList =  new ArrayList<>();
        List<WorkStuDto> unReachedList =  new ArrayList<>();

        for (WorkStuDto workStuDto:studentList){
            Optional<WorkStuDto> optional = list.stream().filter(it -> workStuDto.getId().equals(it.getId()) ).findFirst();
            boolean reached = false;
//            log.info("optional.isPresent:"+optional.isPresent());
            workStuDto.setAchivement(0.0);
            workStuDto.setActualTime(0);
            workStuDto.setReached(0);

            if (optional.isPresent()){
                WorkStuDto item = optional.get();
                workStuDto.setAchivement(item.getAchivement());
                workStuDto.setActualTime(item.getActualTime());
                workStuDto.setReached(item.getReached());
                workStuDto.setCreateTime(item.getCreateTime());
                if (item.getReached().equals(1)){
                    reached = true;
                }
            }
            if (reached) reachedList.add(workStuDto);
            else unReachedList.add(workStuDto);
        }
        finalMap.put("reachedList",reachedList);
        finalMap.put("unReachedList",unReachedList);

//        List<HlifeWorkStudent> unReachedList=hlifeWorkStudentMapper.gethWorkStudentDetail(workId,"0");//未达标
//        List<HlifeWorkStudent> reachedList=hlifeWorkStudentMapper.gethWorkStudentDetail(workId,"1");//已达标
//        workStudentMap.put("reachedList",reachedList);
//        workStudentMap.put("unReachedList",unReachedList);
//        finalMap.put("workStudentMap",workStudentMap);
        return new ResultDTO<>(finalMap);
    }

    public String getActualSecAndMinTime(Integer actualTime){
        String actualSecAndMinTime="";
        if(actualTime%60==0){
            actualSecAndMinTime=String.valueOf((actualTime/60)).concat("分");
            return actualSecAndMinTime;
        }else{
            actualSecAndMinTime=String.valueOf((actualTime/60)).concat("分").concat(String.valueOf((actualTime%60)).concat("秒"));
            return actualSecAndMinTime;
        }
    }

    public static String getActualSecAndMinTimeBySplit(Integer actualTime){
        String actualSecAndMinTime="";
        if(actualTime%60==0){
            actualSecAndMinTime=String.valueOf((actualTime/60)).concat("′");
            return actualSecAndMinTime;
        }else{
            actualSecAndMinTime=String.valueOf((actualTime/60)).concat("′").concat(String.valueOf((actualTime%60)).concat("″"));
            return actualSecAndMinTime;
        }
    }

    //获取星期数字转中文
    private static String getWeekDay(int sortTime) {
        String day = "";
        switch (sortTime) {
            case 1:
                day= "星期一";
                break;
            case 2:
                day= "星期二";
                break;
            case 3:
                day= "星期三";
                break;
            case 4:
                day= "星期四";
                break;
            case 5:
                day= "星期五";
                break;
            case 6:
                day= "星期六";
                break;
            case 7:
                day= "星期日";
                break;
            default:
        }
        return day;
    }

    /**
     * 删除作业及其相关联信息【物理删除】
     * @param workId
     * @return
     */
    /*@Override
    public ResultDTO  deleteWorkInfo(String workId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
//        Map<String,Object> finalMap=Maps.newHashMap();
        HlifeWork hlifeWork=workMapper.getByPrimaryKey(Long.valueOf(workId));
        Integer ruleId=hlifeWork.getRuleId();
        workMapper.deleteByPrimaryKey(Long.valueOf(workId));
        hlifeWorkRuleMapper.deleteByPrimaryKey(ruleId.longValue());

        //是否删除暂不确定，逻辑预留
        String workStudentIds=hlifeWorkStudentMapper.gethWorkStudentIds(workId);//1,2,3,4
        hlifeWorkStudentMapper.deleteWorkStudentByWorkId(workId);
        if(StringUtils.isNotEmpty(workStudentIds)){
            workStudentIds=workStudentIds.replace(",","','");//1','2','3','4
            hlifeWorkStudentHistoryMapper.deleteByPrimaryKeyBatch(workStudentIds);
        }
        return new ResultDTO<>();
    }*/


    /**
     * 删除作业及其相关联信息【逻辑删除】 status=3 已取消就是表示删除的意思
     * @param workId
     * @return
     */
    @Override
    public ResultDTO  deleteWorkInfo(String workId){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }

        String total=hlifeWorkStudentMapper.gethWorkStudentCount(workId);//已经做了该作业的学生人数
        if(!"0".equals(total)){
            throw new MyException(ResultEnum.WORK_IS_NOT_ALLOW_DELETE);
        }
        HlifeWork hlifeWork=new HlifeWork();
        hlifeWork.setId(Long.parseLong(workId));
        hlifeWork.setStatus(3);
        workMapper.update(hlifeWork);

        HlifeWorkStudent hlifeWorkStudent=new HlifeWorkStudent();
        hlifeWorkStudent.setWorkId(Long.parseLong(workId));
        hlifeWorkStudent.setStatus(3);
        hlifeWorkStudentMapper.update(hlifeWorkStudent);

        return new ResultDTO<>();
    }

    /**
     * 结束作业及其相关联信息【结束】 status=2就是表示结束的意思
     * 状态(0未开始 1进行中2已结束3已取消)
     * @param workId
     * @param status
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO  endAndStartWorkInfo(String workId,String status){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }

        if(StringUtils.isEmpty(status)){
            throw new MyException(ResultEnum.STATUS_IS_ILLEGAL);
        }

        if(!(StringUtils.equals(status,"1") || StringUtils.equals(status,"2")  || StringUtils.equals(status,"3"))){
            throw new MyException(ResultEnum.STATUS_IS_ILLEGAL);
        }

        if(StringUtils.equals(status,"3")) {
            String total = hlifeWorkStudentMapper.gethWorkStudentCount(workId);//已经做了该作业的学生人数
            if (!"0".equals(total)) {
                throw new MyException(ResultEnum.WORK_IS_NOT_ALLOW_DELETE);
            }
            HlifeWork hlifeWork = new HlifeWork();
            hlifeWork.setId(Long.parseLong(workId));
            hlifeWork.setStatus(Integer.parseInt(status));
            workMapper.update(hlifeWork);

            HlifeWorkStudent hlifeWorkStudent = new HlifeWorkStudent();
            hlifeWorkStudent.setWorkId(Long.parseLong(workId));
            hlifeWorkStudent.setStatus(Integer.parseInt(status));
            hlifeWorkStudentMapper.update(hlifeWorkStudent);
        }else{
            HlifeWork hlifeWork = new HlifeWork();
            hlifeWork.setId(Long.parseLong(workId));
            hlifeWork.setStatus(Integer.parseInt(status));
            if(StringUtils.equals(status,"1")) {  //当未到作业开始时间时，教师主动点击了“立即开始”，则将作业开始时间直接修改为当前的系统时间
                hlifeWork.setBeginTime(new Date());
            }
            workMapper.update(hlifeWork);

            HlifeWorkStudent hlifeWorkStudent = new HlifeWorkStudent();
            hlifeWorkStudent.setWorkId(Long.parseLong(workId));
            hlifeWorkStudent.setStatus(Integer.parseInt(status));
            hlifeWorkStudentMapper.update(hlifeWorkStudent);
        }
        return new ResultDTO<>();
    }

        /**
         * 个人作业记录【时长模式】
         * @return
         */
    @Override
    public ResultDTO<List<WorkStudentHistoryDto>> getStudentPersonalInfoDetail(Long studentHistoryId){
//        if(workId == null){
//            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
//        }
//        Map<String,Object> finalMap=Maps.newHashMap();
//        //1、学生个人信息
//        Map<String,Object>  sudentPersonalInfoMap=workMapper.getStudentPersonalInfoDetail(workId,studentId);
//        Integer personalSex=Integer.parseInt(String.valueOf(sudentPersonalInfoMap.get("sex")));//该学生的性别
//        sudentPersonalInfoMap.remove("sex");
//        finalMap.put("sudentPersonalInfoMap",sudentPersonalInfoMap);
//
//        //2、作业信息
//        Map<String,Object>  workMap=Maps.newHashMap();
//
//        //作业信息详情
//        Map<String,Object>  workDetailMap=workMapper.getWorkDetail(Long.parseLong(workId));
//        String ruleId=String.valueOf(workDetailMap.get("ruleId"));
//
//        workMap.put("projectName",String.valueOf(workDetailMap.get("projectName")));
//        workMap.put("time",String.valueOf(workDetailMap.get("time")));
//
//        //作业要求
//        HlifeWorkRule hlifeWorkRule=hlifeWorkRuleMapper.getByPrimaryKey(Long.valueOf(ruleId));
//        workMap.put("modelType",hlifeWorkRule.getModelType());//模式(1模拟考试 2限时限数 3数量模式 4时间模式)
//        workMap.put("sex",hlifeWorkRule.getSex());//性别(1男 2女3不限4区分男女)
//
//        if(hlifeWorkRule.getModelType().equals(SportsModelTypeEnum.TIME.getValue())) {   //4时间模式，目前只考虑这个模式
//            if (hlifeWorkRule.getSex() == 4) { //4区分男女
//                if (hlifeWorkRule.getUnit().equals(SportsUnitEnum.UNIT_MINUTE.getValue())) { //3分/4秒
//                    if(personalSex == 1) {
////                        workMap.put("boyDuration", hlifeWorkRule.getBoyDuration().toString().concat("分钟"));
//                        workMap.put("duration", hlifeWorkRule.getBoyDuration().toString().concat("分钟"));
//                    }else{
////                        workMap.put("girlDuration", hlifeWorkRule.getGirlDuration().toString().concat("分钟"));
//                        workMap.put("duration", hlifeWorkRule.getGirlDuration().toString().concat("分钟"));
//                    }
//                } else { //3分/4秒
//                    if(personalSex == 1) {
////                        workMap.put("boyDuration", hlifeWorkRule.getBoyDuration().toString().concat("秒"));
//                        workMap.put("duration", hlifeWorkRule.getBoyDuration().toString().concat("秒"));
//                    }else{
////                       workMap.put("girlDuration", hlifeWorkRule.getGirlDuration().toString().concat("秒"));
//                        workMap.put("duration", hlifeWorkRule.getGirlDuration().toString().concat("秒"));
//                    }
//                }
//            }else{
//                if(hlifeWorkRule.getUnit() == 3){ //3分/4秒
//                    workMap.put("duration",hlifeWorkRule.getDuration().toString().concat("分钟"));
//                }else{ //3分/4秒
//                    workMap.put("duration",hlifeWorkRule.getDuration().toString().concat("秒"));
//                }
//            }
//        }
//        finalMap.put("workMap",workMap);

        //3、作业记录
        /*List<Map<String,Object>> workStudentHistoryList=hlifeWorkStudentHistoryMapper.getListByWorkStudentId(Integer.parseInt(studentHistoryId));
        workStudentHistoryList.forEach(workStudentHistoryMap->{
            Integer actualTime =Integer.parseInt(String.valueOf(workStudentHistoryMap.get("actualTime")));
            String actualSecAndMinTime=getActualSecAndMinTime(actualTime);
            workStudentHistoryMap.put("actualSecAndMinTime",actualSecAndMinTime);
        });*/
        List<WorkStudentHistoryDto> workStudentHistoryList=hlifeWorkStudentHistoryMapper.getListByWorkStudentId(studentHistoryId);
        workStudentHistoryList.forEach(workStudentHistoryDto->{
            Integer actualTime =Integer.parseInt(String.valueOf(workStudentHistoryDto.getActualTime()));
            String actualSecAndMinTime=getActualSecAndMinTime(actualTime);
            workStudentHistoryDto.setActualSecAndMinTime(actualSecAndMinTime);
        });
        return new ResultDTO<>(workStudentHistoryList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultDTO alert(String workId) {
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        //统计耗时【google包下的Stopwatch】
        stopWatch = Stopwatch.createStarted();
        log.info("========教师催促作业开始===================");

            Map<String, Object> map=workMapper.getAlertInfoById(workId);//根据作业id查询该作业被催促过的信息

            if(MapUtils.isNotEmpty(map)){
                //下一次提醒的时间
                Date nextAlertTime=null;
                //上一次推送提醒的时间
                String lastAlertTime=String.valueOf(map.get("lastAlertTime"));
                String tempLastAlertTime=lastAlertTime;
                //该作业的创建时间
                String createTime=String.valueOf(map.get("createTime"));
                //该作业当前已被催促的次数
                int alertCount=Integer.parseInt(String.valueOf(map.get("alertCount")));
//				if(StringUtils.isEmpty(lastAlertTime)) {  //第一次催促
                if(lastAlertTime == null || "null".equals(lastAlertTime)){   //第一次催促
                    lastAlertTime=createTime;
                }
                try {
                    //下一次提醒的时间
                    nextAlertTime= DateUtils.getSomeMinute(sdfAlert.parse(lastAlertTime),interval);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                String nextAlertTimeStr=sdfAlert.format(nextAlertTime);
                String nowTimeStr=sdfAlert.format(new Date());

                int a=nowTimeStr.compareTo(nextAlertTimeStr);
                if(alertCount<totalCount && a >= 0){
                    log.info("==============针对workId为"+workId+"的作业进行第"+alertCount+++"次催促开始============");
                    //todo 微信小程序推送消息逻辑
                    workMapper.updateAlertInfoById(workId);//根据作业id修改该作业被催促过的信息
                    log.info("==============针对workId为"+workId+"的作业进行第"+alertCount+++"次催促结束============");
                }else{
                    if(alertCount>=totalCount){
                        throw new MyException(ResultEnum.WORK_ALERT_IS_OUT_OF_THE_LARGEST_LIMIT);
                    }else{
//						throw new MyException(ResultEnum.WORK_ALERT_IS_LESS_INTERVAL);
//						if(StringUtils.isEmpty(tempLastAlertTime)) {  //第一次催促
                        if(tempLastAlertTime == null || "null".equals(tempLastAlertTime)){  //第一次催促
                            throw new MyException(3030, "你创建该作业时间不足一小时，创建时间是：".concat(lastAlertTime).concat("，暂时不允许催促！"));
                        }else {
                            throw new MyException(3031, "该作业提醒过于频繁，两次催促之间请至少间隔一个小时！上次催促时间是：".concat(lastAlertTime));
                        }
                    }
                }
            }

        log.info("========教师催促作业结束===================");
        log.info("=====请求该接口本次耗时=========：" + stopWatch.elapsed(TimeUnit.MILLISECONDS) + "毫秒");
//        log.info("========制造异常测试===================："+1/0);
        return new ResultDTO<>();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateWorkStatus(){
        //获取当前时间
        LocalDateTime localDateTime =null;
//        String now=localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
//        log.info("=====每隔1秒钟执行一次=============当前时间："+now);

        //log.info("=====定时改变作业状态======【开始】=======");

        List<String> unStartWorkIdList= com.google.common.collect.Lists.newArrayList();//状态为未开始的作业ID列表
        List<String> startingWorkIdList= com.google.common.collect.Lists.newArrayList();//状态为进行中的作业ID列表
//        根据状态查询作业  0未开始 1进行中2已结束
        //查询状态为未开始的作业
        List<Map<String,Object>> unStartWorkList=workMapper.getWorkByStatus("0");
//        unStartWorkList.forEach(unStartWorkMap->{
        for (Map<String,Object> unStartWorkMap:unStartWorkList) {
            //获取当前时间
            localDateTime = LocalDateTime.now();//尽量减少误差，所以每次都是重新生成
//                    String now = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            String now = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String id = String.valueOf(unStartWorkMap.get("id"));
            String beginTime = String.valueOf(unStartWorkMap.get("beginTime"));
//                    if (now.equals(beginTime)) {
            if (now.compareTo(beginTime)>=0) {
                unStartWorkIdList.add(id);
            }
//        });
        }

        //查询状态为进行中的作业
        List<Map<String,Object>> startingWorkList=workMapper.getWorkByStatus("1");
//        startingWorkList.forEach(startingWorkMap->{
        for (Map<String,Object> startingWorkMap:startingWorkList) {
            //获取当前时间
            localDateTime = LocalDateTime.now();//尽量减少误差，所以每次都是重新生成
//            String now=localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
            String now=localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            String id=String.valueOf(startingWorkMap.get("id"));
            String endTime=String.valueOf(startingWorkMap.get("endTime"));
//            if(now.equals(endTime)){
            if(now.compareTo(endTime)>=0){
                startingWorkIdList.add(id);
            }
//        });
        }

        //批量将作业状态由未开始变为进行中
        if(!CollectionUtils.isEmpty(unStartWorkIdList)){
            String unStartWorkIds = StringUtils.join(unStartWorkIdList.toArray(new String[0]), "','");//1','2','3','4
            //log.info("===============unStartWorkIds==============:"+unStartWorkIds);
            workMapper.updateWorkStatusBatch(unStartWorkIds,"1");
        }

        //批量将作业状态由进行中变为已结束
        if(!CollectionUtils.isEmpty(startingWorkIdList)){
            String startingWorkIds = StringUtils.join(startingWorkIdList.toArray(new String[0]), "','");//1','2','3','4
            //log.info("===============startingWorkIds==============:"+startingWorkIds);
            workMapper.updateWorkStatusBatch(startingWorkIds,"2");
        }
        //log.info("=====定时改变作业状态======【结束】=======");
        //log.info("=====本次共查询出"+unStartWorkList.size()+"个作业是未开始状态，有"+startingWorkList.size()+"个作业是进行中状态，其中，需要将未开始状态转变为进行中的作业有"+unStartWorkIdList.size()+"个，需要将进行中状态转变为已结束的作业有"+startingWorkIdList.size()+"个。=======");
    }


    //===========================================小程序端=============【begin】===============================================================

    /**
     * 学生在小程序端查询属于自己的作业列表/作业详情
     * @param studentId
     * @param workId
     * @return
     */
    @Override
    public ResultDTO<PageInfo<WorkDto>> getWorkListByStudentId(String studentId, String workId, Integer reached, int pageNo, int pageSize){
        if(StringUtils.isEmpty(studentId)){
            throw new MyException(ResultEnum.STUDENT_ID_IS_NULL);
        }
        Page<WorkDto> page = PageHelper.startPage(pageNo, pageSize,true);
        List<WorkDto>  studentWorkList=workMapper.getWorkListByStudentId(studentId,workId,reached);
        //========================作业要求里面选择了男生/女生时，即使老师选择了全班学生，那么也只是针对性的男生/女生才可以看到改作业====【begin】=====================================
        // 查询学生性别
//        Integer sex=hlifeWorkStudentMapper.getStudentSex(studentId);//查询当前用户的性别(1男/2女)
        //========================作业要求里面选择了男生/女生时，即使老师选择了全班学生，那么也只是针对性的男生/女生才可以看到改作业====【end】=====================================

//        for(WorkDto studentWorkMap:studentWorkList) {
//            //studentWorkList.forEach(studentWorkMap->{
//            String ymTime = studentWorkMap.getYmTime();
//            String dTime = studentWorkMap.getDTime();
//            Integer duration = studentWorkMap.getDuration();
//            Integer unit = studentWorkMap.getUnit();
//            Integer ruleSex = studentWorkMap.getRuleSex();
//            if( ruleSex.equals(1) || ruleSex.equals(2)){
//                if (!sex.equals(ruleSex)){
//                    continue;
//                }
//            }
////            double diff=getDoubleMarginZheng(sdf1.format(new Date()),ymTime.replace("年","-").replace("月","-").replace("日","-"));
//            double diff = getDoubleMarginZheng(format22.format(new Date()), ymTime);
//            //最近几天就不显示年月日了
//            if (diff == 0.0) {
//                studentWorkMap.setTime("今天".concat(dTime).concat("前"));
//            } else if (diff == -1.0) {
//                studentWorkMap.setTime("明天".concat(dTime).concat("前"));
//            } else if (diff == -2.0) {
//                studentWorkMap.setTime("后天".concat(dTime).concat("前"));
//            } else {
////                studentWorkMap.put("time",ymTime.concat(" ").concat(dTime).concat("前"));
//                try {
//                    studentWorkMap.setTime(format.format(format22.parse(ymTime).getTime()).concat(" ").concat(dTime).concat("前"));
//                } catch (ParseException e) {
//                    log.info("========ParseException=============:" + e.getMessage());
//                }
//            }
//
//            if (unit == 3) { //3分/4秒
//                studentWorkMap.setDurationFormat(duration.toString().concat("分钟"));
//                studentWorkMap.setTotalTime(duration * 60);
//            } else { //3分/4秒
//                studentWorkMap.setDurationFormat(duration.toString().concat("秒"));
//                studentWorkMap.setTotalTime(duration);
//            }
//
//            studentWorkMap.setYmTime(null);
//            studentWorkMap.setDTime(null);
//            studentWorkMap.setUnit(null);
//        }

        /*if(StringUtils.isNotEmpty(workId)){
            //        某个作业已完成的人数
            int total=workMapper.getCompletedByWorkId(workId);
//            finalMap.put("total",total);
            studentWorkList.get(0).put("total",total);
        }*/

//        finalMap.put("studentWorkList",studentWorkList);

        //PageInfo<Map<String,Object>> pageInfo = new PageInfo<Map<String,Object>>(studentWorkList);
//        PageInfo<Map<String,Object>> pageInfo = new PageInfo<Map<String,Object>>(studentWorkSexList);
//        //pageInfo.setTotal(page.getTotal());
//        if(!CollectionUtils.isEmpty(studentWorkSexList)) {
//            pageInfo.setTotal(studentWorkSexList.size());
//        }else{
//            pageInfo.setTotal(0);
//        }
        PageInfo<WorkDto> pageInfo = new PageInfo<>(studentWorkList);
        pageInfo.setTotal(page.getTotal());
        return new ResultDTO<>(pageInfo);
    }

    /**
     * 个人作业记录【时长模式】【小程序端】
     * @param studentHistoryId
     * @return
     */
    @Override
    public ResultDTO<PageInfo<WorkStudentHistoryDto>> getStudentWorkHistory(Long studentHistoryId,int pageNo,int pageSize){
        Page<Map<String,Object>> page = PageHelper.startPage(pageNo, pageSize);
        List<WorkStudentHistoryDto> workStudentHistoryList=hlifeWorkStudentHistoryMapper.getListByWorkStudentId(studentHistoryId);
        workStudentHistoryList.forEach(workStudentHistoryDto->{
            Integer actualTime =Integer.parseInt(String.valueOf(workStudentHistoryDto.getActualTime()));
            String actualSecAndMinTime=getActualSecAndMinTime(actualTime);
            workStudentHistoryDto.setActualSecAndMinTime(actualSecAndMinTime);
        });
        PageInfo<WorkStudentHistoryDto> pageInfo = new PageInfo<WorkStudentHistoryDto>(workStudentHistoryList);
        pageInfo.setTotal(page.getTotal());
//        return pageInfo;
        return new ResultDTO<>(pageInfo);
//        return new ResultDTO<>(workStudentHistoryList);
    }

    /**
     * 获取某个作业已达标/未达标的学生列表
     * @param workId
     * @param reached
     * @return
     */
    @Override
    public ResultDTO<PageInfo<WorkStuDto>> getUnAndReachStudentList(String workId,Integer reached, int pageNo,int pageSize){
        if(StringUtils.isEmpty(workId)){
            throw new MyException(ResultEnum.WORK_ID_IS_NULL);
        }
        Page<WorkStuDto> page = PageHelper.startPage(pageNo, pageSize);
        List<WorkStuDto> workStudentHistoryList = hlifeWorkStudentHistoryMapper.getUnAndReachStudentList(workId,reached);
        PageInfo<WorkStuDto> pageInfo = new PageInfo<>(workStudentHistoryList);
        pageInfo.setTotal(page.getTotal());
        return new ResultDTO<>(pageInfo);
    }

    @Override
    public List<SportsHomeInfoDto> getStudentWorkList(Map<String,Object> params, int pageNo, int pageSize)
    {
        List<SportsHomeInfoDto> workList = new ArrayList<>();

        try {
            //========================作业要求里面选择了男生/女生时，即使老师选择了全班学生，那么也只是针对性的男生/女生才可以看到改作业====【begin】=====================================
            // 查询学生性别
            Integer sex=hlifeWorkStudentMapper.getStudentSex(String.valueOf(params.get("studentId")));//查询当前用户的性别(1男/2女)
            //========================作业要求里面选择了男生/女生时，即使老师选择了全班学生，那么也只是针对性的男生/女生才可以看到改作业====【end】=====================================
            Page<Map<String,Object>> page = PageHelper.startPage(pageNo, pageSize, true);
            PageInfo<Map<String,Object>> pageInfo = new PageInfo<>(hlifeWorkStudentMapper.getStudentWorkList(params));
            List<Map<String,Object>> studentWorkList = pageInfo.getList();
            for(Map<String,Object> studentWorkMap:studentWorkList) {
            //studentWorkList.forEach(studentWorkMap-> {
                Integer ruleSex = Integer.valueOf(String.valueOf(studentWorkMap.get("ruleSex")));//性别(1男 2女3不限4区分男女)
                if (ruleSex.equals(1) || ruleSex.equals(2)) {
                    if (!sex.equals(ruleSex)) {
                        continue;
                    }
                }

                SportsHomeInfoDto sportsHomeInfoDto = new SportsHomeInfoDto();
                sportsHomeInfoDto.setType(SportsHomeContentEnum.HOME_WORK.getCode());
                sportsHomeInfoDto.setId(Long.parseLong((String) studentWorkMap.get("workId")));
                sportsHomeInfoDto.setTitle((String) studentWorkMap.get("content"));
                sportsHomeInfoDto.setProjectName((String) studentWorkMap.get("projectName"));
                sportsHomeInfoDto.setWorkId((String)studentWorkMap.get("workId"));
                sportsHomeInfoDto.setTarget(((String) studentWorkMap.get("duration") + "分钟"));
                sportsHomeInfoDto.setFinishCount((String) studentWorkMap.get("finishCount"));
                sportsHomeInfoDto.setAuthor((String) studentWorkMap.get("author"));
                sportsHomeInfoDto.setHeadImg((String) studentWorkMap.get("headImg"));
                sportsHomeInfoDto.setStatus((String) studentWorkMap.get("status"));

                String ymTime = String.valueOf(studentWorkMap.get("ymTime"));//示例值：2021年3月27日
                String dTime = String.valueOf(studentWorkMap.get("dTime"));//示例值：14:20
                Integer duration = Integer.valueOf(String.valueOf(studentWorkMap.get("duration")));
                Integer unit = Integer.valueOf(String.valueOf(studentWorkMap.get("unit")));//3分/4秒

                double diff = getDoubleMarginZheng(format22.format(new Date()), ymTime);
                //最近几天就不显示年月日了
                if (diff == 0.0) {
                    sportsHomeInfoDto.setDeadline("今天".concat(dTime).concat("前"));
                } else if (diff == -1.0) {
                    sportsHomeInfoDto.setDeadline("明天".concat(dTime).concat("前"));
                } else if (diff == -2.0) {
                    sportsHomeInfoDto.setDeadline("后天".concat(dTime).concat("前"));
                } else {
                    try {
                        sportsHomeInfoDto.setDeadline(format.format(format22.parse(ymTime).getTime()).concat(" ").concat(dTime).concat("前"));
                    } catch (ParseException e) {
                        log.error("========ParseException=============:" + e.getMessage());
                    }
                }

                if (unit == 3) { //3分/4秒
                    studentWorkMap.put("duration", duration.toString().concat("分钟"));
                    studentWorkMap.put("totalTime", duration * 60);
                } else { //3分/4秒
                    studentWorkMap.put("duration", duration.toString().concat("秒"));
                    studentWorkMap.put("totalTime", duration);
                }

                workList.add(sportsHomeInfoDto);
                //});
            }
        } catch (Exception e) {
            log.error("getStudentWorkList异常" , e);
        }
        return workList;
    }

//===========================================小程序端=============【end】===============================================================

//===========================================PC端=============【begin】===============================================================
    //跳绳作业个人统计【PC端】
    @Override
    public ResultDTO getStudentPersonalInfoDetailForPc(Long studentId, int pageNo, int pageSize){
        if(studentId == null){
            throw new MyException(ResultEnum.STUDENT_ID_IS_NULL);
        }
        Map<String,Object> finalMap=Maps.newHashMap();

        //1、学生个人信息和作业统计数量以及百分比信息
        Map<String,Object>  sudentPersonalAndWorkInfoMap=workMapper.getStudentPersonalInfoDetailForPc(studentId);
        finalMap.put("sudentPersonalAndWorkInfoMap",sudentPersonalAndWorkInfoMap);

        Page<WorkStudentHistoryForPcDto> page = PageHelper.startPage(pageNo, pageSize);
        //2、查询某个学生所做的所有作业
        List<WorkStudentHistoryForPcDto> workStudentForPcList=hlifeWorkStudentMapper.gethWorkByStudentId(studentId);

        workStudentForPcList.forEach(workStudentHistoryForPcDto->{
            Integer duration=workStudentHistoryForPcDto.getDuration();
            Integer unit=workStudentHistoryForPcDto.getUnit();
            if (unit == 3) { //3分/4秒
                workStudentHistoryForPcDto.setDuration(duration*60);
                workStudentHistoryForPcDto.setDurationMinAndSec(duration.toString().concat("分钟"));
            } else { //3分/4秒
                workStudentHistoryForPcDto.setDurationMinAndSec(duration.toString().concat("秒"));
            }
        });

        PageInfo<WorkStudentHistoryForPcDto> pageInfo = new PageInfo<WorkStudentHistoryForPcDto>(workStudentForPcList);
        pageInfo.setTotal(page.getTotal());

        finalMap.put("workStudentForPcList",pageInfo);
        //finalMap.put("workStudentForPcList",workStudentForPcList);
        //finalMap.put("total",page.getTotal());
        return new ResultDTO(finalMap);
    }

    //学校大屏【不归我写】
    /*@Override
    public ResultDTO getSchoolBigScreen(String schoolId,String gradeId,String type){
        if(StringUtils.isEmpty(schoolId)){
            throw new MyException(ResultEnum.ORG_ID_IS_NULL);
        }

        if(StringUtils.isEmpty(gradeId)){
            throw new MyException(ResultEnum.GRADE_ID_IS_NULL);
        }

        if(!(StringUtils.equals(type,"1") || StringUtils.equals(type,"2") || StringUtils.equals(type,"3") || StringUtils.equals(type,"4") || StringUtils.equals(type,"5") || StringUtils.equals(type,"6") || StringUtils.equals(type,"7"))){
            throw new MyException(ResultEnum.SPORTS_TYPE_IS_ILLEGAL);
        }

        //年级数量
        //班级数量
        //学生总人数
        //男生人数
        //女生人数
        //任课教师人数

        return new ResultDTO();
    }*/


//===========================================PC端=============【end】===============================================================

    /** 日期格式yyyy-MM-dd字符串常量 */
    private static final String DATE_FORMAT = "yyyy-MM-dd";
    private static SimpleDateFormat sdf_date_format = new SimpleDateFormat(DATE_FORMAT);

    /**
     * 比较两个日期相差的天数 【整数】
     * @author dylan_xu
     * @date Mar 11, 2012
     * @param date1
     * @param date2
     * @return
     */
    public static double getDoubleMarginZheng(String date1, String date2) {
        double margin;
        try {
            ParsePosition pos = new ParsePosition(0);
            ParsePosition pos1 = new ParsePosition(0);
            Date dt1 = sdf_date_format.parse(date1, pos);
            Date dt2 = sdf_date_format.parse(date2, pos1);
            long l = dt1.getTime() - dt2.getTime();
            margin = (l / (24 * 60 * 60 * 1000.00));
            return margin;
        } catch (Exception e) {
            log.debug("getDoubleMarginZheng():" + e.toString());
            return 0;
        }
    }

}
